/**
 * 图片处理工具函数
 */

import sharp from 'sharp';
import fs from 'fs';
import path from 'path';
import config from '../config/index.js';

/**
 * 检查图片是否需要缩放
 * @param {string} imagePath 图片文件路径
 * @param {number} maxWidth 最大宽度
 * @param {number} maxHeight 最大高度
 * @returns {Promise<{needResize: boolean, width: number, height: number, newWidth?: number, newHeight?: number}>}
 */
export async function checkImageResize(imagePath, maxWidth, maxHeight) {
  try {
    const metadata = await sharp(imagePath).metadata();
    const { width, height } = metadata;
    
    if (!width || !height) {
      throw new Error('无法获取图片尺寸信息');
    }
    
    // 检查是否超出限制
    if (width <= maxWidth && height <= maxHeight) {
      return {
        needResize: false,
        width,
        height
      };
    }
    
    // 计算缩放比例，保持宽高比
    const widthRatio = maxWidth / width;
    const heightRatio = maxHeight / height;
    const ratio = Math.min(widthRatio, heightRatio);
    
    const newWidth = Math.round(width * ratio);
    const newHeight = Math.round(height * ratio);
    
    return {
      needResize: true,
      width,
      height,
      newWidth,
      newHeight
    };
  } catch (error) {
    console.error('检查图片尺寸失败:', error);
    throw new Error('图片格式不支持或文件损坏');
  }
}

/**
 * 缩放图片
 * @param {string} inputPath 输入图片路径
 * @param {string} outputPath 输出图片路径
 * @param {number} width 目标宽度
 * @param {number} height 目标高度
 * @param {number} quality 图片质量 (1-100)
 * @returns {Promise<void>}
 */
export async function resizeImage(inputPath, outputPath, width, height, quality = 85) {
  try {
    const image = sharp(inputPath);
    const metadata = await image.metadata();
    
    // 根据原始格式选择输出格式
    let outputImage = image.resize(width, height, {
      fit: 'inside', // 保持宽高比，图片完全包含在指定尺寸内
      withoutEnlargement: true // 不放大小图片
    });
    
    // 根据原始格式设置输出选项
    switch (metadata.format) {
      case 'jpeg':
      case 'jpg':
        outputImage = outputImage.jpeg({ quality });
        break;
      case 'png':
        outputImage = outputImage.png({ 
          quality,
          compressionLevel: 6 
        });
        break;
      case 'webp':
        outputImage = outputImage.webp({ quality });
        break;
      case 'gif':
        // GIF 保持原格式，不设置质量
        outputImage = outputImage.gif();
        break;
      default:
        // 默认转换为 JPEG
        outputImage = outputImage.jpeg({ quality });
        break;
    }
    
    await outputImage.toFile(outputPath);
    console.log(`图片缩放成功: ${width}x${height}, 质量: ${quality}%`);
  } catch (error) {
    console.error('图片缩放失败:', error);
    throw new Error('图片处理失败');
  }
}

/**
 * 处理头像图片
 * @param {string} filePath 图片文件路径
 * @returns {Promise<{processed: boolean, originalSize?: {width: number, height: number}, newSize?: {width: number, height: number}}>}
 */
export async function processAvatarImage(filePath) {
  try {
    const { maxWidth, maxHeight, quality } = config.upload.avatar;
    
    // 检查配置是否有效
    if (!maxWidth || !maxHeight || maxWidth <= 0 || maxHeight <= 0) {
      console.log('头像尺寸配置无效，跳过图片处理');
      return { processed: false };
    }
    
    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      throw new Error('图片文件不存在');
    }
    
    // 检查是否需要缩放
    const resizeInfo = await checkImageResize(filePath, maxWidth, maxHeight);
    
    if (!resizeInfo.needResize) {
      console.log(`图片尺寸 ${resizeInfo.width}x${resizeInfo.height} 在限制范围内，无需处理`);
      return {
        processed: false,
        originalSize: {
          width: resizeInfo.width,
          height: resizeInfo.height
        }
      };
    }
    
    console.log(`图片尺寸 ${resizeInfo.width}x${resizeInfo.height} 超出限制，开始缩放到 ${resizeInfo.newWidth}x${resizeInfo.newHeight}`);
    
    // 创建临时文件路径
    const tempPath = filePath + '.tmp';
    
    // 缩放图片到临时文件
    await resizeImage(filePath, tempPath, resizeInfo.newWidth, resizeInfo.newHeight, quality);
    
    // 替换原文件
    fs.renameSync(tempPath, filePath);
    
    return {
      processed: true,
      originalSize: {
        width: resizeInfo.width,
        height: resizeInfo.height
      },
      newSize: {
        width: resizeInfo.newWidth,
        height: resizeInfo.newHeight
      }
    };
  } catch (error) {
    console.error('处理头像图片失败:', error);
    
    // 清理临时文件
    const tempPath = filePath + '.tmp';
    if (fs.existsSync(tempPath)) {
      try {
        fs.unlinkSync(tempPath);
      } catch (cleanupError) {
        console.error('清理临时文件失败:', cleanupError);
      }
    }
    
    throw error;
  }
}

/**
 * 获取图片信息
 * @param {string} filePath 图片文件路径
 * @returns {Promise<{width: number, height: number, format: string, size: number}>}
 */
export async function getImageInfo(filePath) {
  try {
    const metadata = await sharp(filePath).metadata();
    const stats = fs.statSync(filePath);
    
    return {
      width: metadata.width || 0,
      height: metadata.height || 0,
      format: metadata.format || 'unknown',
      size: stats.size
    };
  } catch (error) {
    console.error('获取图片信息失败:', error);
    throw new Error('无法读取图片信息');
  }
}

export default {
  checkImageResize,
  resizeImage,
  processAvatarImage,
  getImageInfo
};
